package ServerSide;

import java.net.Socket;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.JTextArea;



/**
 * @author Avishai Kopeliansky 
 * @ID 066717752
 * @author David Shimshon
 * @ID 038185617
 */
public class ClientHandling {
	private static final Hashtable<String,ClientSock> clients = new Hashtable<String, ClientSock>();
	private static final Vector<ClientSock> tclients = new Vector<ClientSock>();
	private boolean flag = true;	
	private JTextArea jta;

	
	/**
	 * Constructor 
	 * @param jta Textarea to append the Text (meant for server app console)
	 */
	public ClientHandling(JTextArea jta){
		this.jta = jta;
		
	}
	/**
	 * Permanently adding the client 
	 * @param csock Client socket
	 */
	public synchronized void permAdd(ClientSock csock){
		//System.out.println(csock == false);
		clients.put(csock.getNames(),csock);
	//	this.jta.append(csock.getNames()+" Has authenticated\r\n");
		broadCast(csock.getNames()+" Has authenticated\r\n");		
		try {
			Thread.sleep(100L);
		} catch (InterruptedException e) {
		}
		sysMsg("<UserList><"+this.clientList()+">");
	}

	/**
	 * Temporarily adding a client for authorization 
	 * @param csock client Socket
	 */
	public synchronized void tempAdd(Socket csock){
		this.jta.append("User Joind\n");
		tclients.add(new ClientSock(csock,this));
		tclients.lastElement().start();	
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
		}

	}

	/**
	 * Get HashTable
	 * @return Hashtable with Keys<String> and values<ClientSock>
	 */
	@SuppressWarnings("static-access")
	public Hashtable<String,ClientSock> getTable(){
		return this.clients;
	}
	/**
	 * Synchronized removal of the temp value in the vector to make room for other connections.
	 * @param ID the Connection ID to close
	 */
	public synchronized void removeTemp(int ID){		
		for(int i = 0 ; i < tclients.size() ; i++){
			if(tclients.elementAt(i).getID() == (ID))
			{
				System.out.println("Removing:"+tclients.elementAt(i).getNames());
				tclients.remove(i);
				System.out.println("Removed");
			}
		}
	}

	/**
	 * Sending a Personal Message to a user
	 * @param name Name of the user
	 * @param msg Message to dispatch
	 * @return True if able to find user, False if he doesnt exist
	 */
	public boolean sendMsg(String name , String msg){	
		if(clients.containsKey(name)){
			clients.get(name).sendPMsg(msg);			
			return true;

		}
		else			
		{
			this.checkAlive();
			return false;
		}
		
	}
	
	/**
	 * System Messages: Usage for Server console ONLY!
	 * @param msg Message to broadcast
	 */
	
	public void sysMsg(String msg){
		for(String f : clients.keySet()){
			clients.get(f).sendSMsg(msg);
		}
		this.jta.append(msg+"\n");
		this.jta.setCaretPosition(jta.getDocument().getLength());
	}

	/**
	 * Broadcast message to all alive users in the list
	 * @param msg Message to deliver 
	 */
	public void broadCast(String msg){	
		for(String f : clients.keySet()){
			clients.get(f).sendMsg(msg);
		}
		this.jta.append(msg+"\n");
		this.jta.setCaretPosition(jta.getDocument().getLength());
	}

	/**
	 * Checks for dead connections and close and remove them
	 * 
	 */
	public void checkAlive(){
		for(String f : clients.keySet())
		{
			if(!clients.get(f).isAlive()){
				broadCast("User "+f+", has left the Server");
				clients.remove(f);
			}
		}
	}

	/**
	 * Remove a leaving user from the Table
	 * @param s Name of the user
	 */
	public void removeMe(String s){
		this.broadCast("User "+s+", has left the Server");
		clients.remove(s);
		sysMsg("<UserList><"+this.clientList()+">");
	}

	/**
	 * Send user list
	 * @return String user list
	 */
	public synchronized String clientList(){
		String t = "";
		for(String f : clients.keySet())
			t = t+f+",";
				return t;
	}


	/**
	 * Checks if the list already has a Key of the sort.
	 * @param s Name of user
	 * @return True if exists, False if doesnt
	 */
	public boolean hasName(String s) {
		// TODO Auto-generated method stub
		return clients.containsKey(s);
	}

	/**
	 * Shutdown the Chat Handler
	 */
	public void shutDown(){
		
		for(String f : clients.keySet()){
			clients.get(f).shutDown();
			clients.remove(f);
		
		}
		this.flag = false;
		System.out.println("i is:"+0 +", and we're shutting down");
	}

	/**
	 * Handler status
	 * @return flag 
	 */
	public boolean getFlag(){
		return this.flag;
	}
}
